// Package main 提供服务操作的实际实现
package go_service

import (
	"context"
	"fmt"
	"os"
	"os/exec"
	"strings"
	"time"
)

// Start 启动服务
//
// 参数:
//   ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//   error: 如果启动成功返回nil，否则返回对应的错误
//
// 示例:
//   service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//   ctx := context.Background()
//   
//   if err := service.Start(ctx); err != nil {
//       fmt.Printf("启动服务失败: %v\n", err)
//       return
//   }
//   fmt.Println("服务启动成功")
func (s *Service) Start(ctx context.Context) error {
	// 检查服务是否已运行
	if s.IsRunning() {
		return fmt.Errorf("service %s is already running", s.Name)
	}

	// 创建命令
	cmd := exec.CommandContext(ctx, s.ExecPath, s.Args...)
	cmd.Dir = s.WorkingDir
	cmd.Env = s.Env

	// 启动命令
	if err := cmd.Start(); err != nil {
		return fmt.Errorf("failed to start service %s: %w", s.Name, err)
	}

	// 非阻塞执行，记录进程ID等信息
	go func() {
		// 等待命令完成
		if err := cmd.Wait(); err != nil {
			// 记录错误日志
			fmt.Fprintf(os.Stderr, "service %s exited with error: %v\n", s.Name, err)
		} else {
			// 记录服务正常退出
			fmt.Printf("service %s exited normally\n", s.Name)
		}
	}()

	return nil
}

// Stop 停止服务
func (s *Service) Stop(ctx context.Context) error {
	// 检查服务是否运行
	if !s.IsRunning() {
		return fmt.Errorf("service %s is not running", s.Name)
	}

	// 对于Systemd服务，可以使用systemctl命令
	cmd := exec.CommandContext(ctx, "systemctl", "stop", s.Name)
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to stop service %s: %w", s.Name, err)
	}

	return nil
}

// RestartService 重启服务
func (s *Service) RestartService(ctx context.Context) error {
	// 先停止服务
	if err := s.Stop(ctx); err != nil {
		// 如果服务未运行，我们仍然尝试启动它
		if !strings.Contains(err.Error(), "is not running") {
			return err
		}
	}

	// 短暂延迟确保服务完全停止
	time.Sleep(1 * time.Second)

	// 启动服务
	return s.Start(ctx)
}

// IsRunning 检查服务是否正在运行
func (s *Service) IsRunning() bool {
	// 这里使用systemctl status命令作为示例
	cmd := exec.Command("systemctl", "status", s.Name)
	output, err := cmd.CombinedOutput()
	if err != nil {
		// 如果命令执行失败，服务可能未运行
		return false
	}

	// 检查输出中是否包含"active (running)"
	return strings.Contains(string(output), "active (running)")
}

// Status 获取服务状态
func (s *Service) Status() (string, error) {
	cmd := exec.Command("systemctl", "status", s.Name)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("failed to get status for service %s: %w\noutput: %s", s.Name, err, string(output))
	}

	return string(output), nil
}

// Enable 启用开机启动
func (s *Service) Enable(ctx context.Context) error {
	cmd := exec.CommandContext(ctx, "systemctl", "enable", s.Name)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to enable service %s: %w\noutput: %s", s.Name, err, string(output))
	}
	return nil
}

// Disable 禁用开机启动
func (s *Service) Disable(ctx context.Context) error {
	cmd := exec.CommandContext(ctx, "systemctl", "disable", s.Name)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to disable service %s: %w\noutput: %s", s.Name, err, string(output))
	}
	return nil
}
